/*-------------------------------------------------------------------------
 *
 * snapbuild.h
 *	  从 replication/logical/snapbuild.c 导出。
 *
 * Copyright (c) 2012-2022, PostgreSQL Global Development Group
 *
 * src/include/replication/snapbuild.h
 *
 *-------------------------------------------------------------------------
 */
#ifndef SNAPBUILD_H
#define SNAPBUILD_H

#include "access/xlogdefs.h"
#include "utils/snapmgr.h"

typedef enum
{
	/*
	 * 初始状态，我们还不能做太多。
	 */
	SNAPBUILD_START = -1,

	/*
	 * 收集已提交的事务，以构建初始目录快照。
	 */
	SNAPBUILD_BUILDING_SNAPSHOT = 0,

	/*
	 * 我们已经收集了足够的信息来解码在此之后启动的事务中的元组。
	 *
	 * 一旦我们达到这一点，就开始收集更改。我们目前无法应用这些更改，因为它们可能基于在到达 FULL_SNAPSHOT 时仍在运行的事务。
	 */
	SNAPBUILD_FULL_SNAPSHOT = 1,

	/*
	 * 找到在 SNAPBUILD_FULL_SNAPSHOT 之后的一个点，所有在该点运行的事务都已完成。在我们达到这一点之前，我们会推迟调用任何提交回调。
	 */
	SNAPBUILD_CONSISTENT = 2
} SnapBuildState;

/* 前向声明，以便我们不必向公众公开结构 */
struct SnapBuild;
typedef struct SnapBuild SnapBuild;

/* 前向声明，以便我们不必包含 reorderbuffer.h */
struct ReorderBuffer;

/* 前向声明，以便我们不必包含 heapam_xlog.h */
struct xl_heap_new_cid;
struct xl_running_xacts;

extern void CheckPointSnapBuild(void);

extern SnapBuild *AllocateSnapshotBuilder(struct ReorderBuffer *cache,
										  TransactionId xmin_horizon, XLogRecPtr start_lsn,
										  bool need_full_snapshot,
										  XLogRecPtr two_phase_at);
extern void FreeSnapshotBuilder(SnapBuild *cache);

extern void SnapBuildSnapDecRefcount(Snapshot snap);

extern Snapshot SnapBuildInitialSnapshot(SnapBuild *builder);
extern const char *SnapBuildExportSnapshot(SnapBuild *snapstate);
extern void SnapBuildClearExportedSnapshot(void);
extern void SnapBuildResetExportedSnapshotState(void);

extern SnapBuildState SnapBuildCurrentState(SnapBuild *snapstate);
extern Snapshot SnapBuildGetOrBuildSnapshot(SnapBuild *builder,
											TransactionId xid);

extern bool SnapBuildXactNeedsSkip(SnapBuild *snapstate, XLogRecPtr ptr);
extern XLogRecPtr SnapBuildGetTwoPhaseAt(SnapBuild *builder);
extern void SnapBuildSetTwoPhaseAt(SnapBuild *builder, XLogRecPtr ptr);

extern void SnapBuildCommitTxn(SnapBuild *builder, XLogRecPtr lsn,
							   TransactionId xid, int nsubxacts,
							   TransactionId *subxacts);
extern bool SnapBuildProcessChange(SnapBuild *builder, TransactionId xid,
								   XLogRecPtr lsn);
extern void SnapBuildProcessNewCid(SnapBuild *builder, TransactionId xid,
								   XLogRecPtr lsn, struct xl_heap_new_cid *cid);
extern void SnapBuildProcessRunningXacts(SnapBuild *builder, XLogRecPtr lsn,
										 struct xl_running_xacts *running);
extern void SnapBuildSerializationPoint(SnapBuild *builder, XLogRecPtr lsn);

extern void SnapBuildXidSetCatalogChanges(SnapBuild *builder, TransactionId xid,
										  int subxcnt, TransactionId *subxacts,
										  XLogRecPtr lsn);
#endif							/* SNAPBUILD_H */
